<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<script>

	function extend2(Child, Parent) {
		var p = Parent.prototype;
		var c = Child.prototype;
		for(var i in p){
			c[i] = p[i];
		}
		c.uber = p;
	}
	// 我们通过一个简单的循环遍历了函数所接受的所有属性。在之前的实例中，如果子对象需要访问父对象的方法，我们可以通过设置uber属性来实现。而这里的情况有所不同，由于我们已经完成了对Child的原型进行扩展，不需要再去充值Child.prototype.consturctor属性，因为他不会再被完全覆盖了。因此在这里，consturctro属性所指向的值是正确的
	// 与之前的方法相比，这个方法在效率上更好，因为这里执行的是子对象原型的逐一拷贝，而非简单的原型链查询。所以我们必须要记住，这种方式仅适用于包含基本数据类型的对象，所有的对象类型（包括函数与数组）都是不可复制的，因为他们只支持引用传递
	// 下面我们来看看具体的应用示例，以下有两个构造器函数Shape()和TwoDShape()。其中，Shape()的原型中包含了一个基本类型属性name，和一个非基本数据类型toString()方法
	var Shape = function() {};
	var TwoDShape = function() {};
	Shape.prototype.name = 'shape';
	Shape.prototype.toString = function() {
		return this.uber
			? this.uber.toString() +'，'+this.name
			: this.name;
	}
	// 如果我们通过extend()方法来实现继承，那么name属性既不会是TwoDShape()实例的属性，也不会成为其原型对象的属性，但是子对象依然可以通过继承方式来访问该属性
	extend2(TwoDShape, Shape);
	var td = new TwoDShape();
	console.log(td.name);
	console.log(TwoDShape.prototype.name);
	console.log(td.__proto__.name);
	console.log(td.hasOwnProperty('name'));
	console.log(td.__proto__.hasOwnProperty('name'));

	// 而如果继承是通过extend2()方法来实现的，TwoDShape()的原型中就会拷贝获得属于自己的name属性。同样的，其中也会拷贝属于自己的toString()方法，但这只是一个函数引用，函数本身并没有被再次创建
	extend2(TwoDShape, Shape);
	var td = new TwoDShape();
	console.log(td.__proto__.hasOwnProperty('name'));
	console.log(td.__proto__.hasOwnProperty('toString'));
	console.log(td.__proto__.toString === Shape.prototype.toString);

	// 上面两个toString()方法实际是同一个函数对象。之所以这样做，也是因为这样的方法重建其实是完全没有必要的
	// 所以，之所以说extend2()方法的效率要低于extend()方法，主要是前者对部分原型属性做了重建。当然了，这对于只包含基本数据类型的对象来说，未必真的就是如此糟糕。而且，这样做还能使属性查找操作更多的停留在对象本身，从而减少原型链上的查找。
	// 现在，让我们再来回顾一下定义uber属性的整个过程。这一次的做法有别于之前的通过Parsetnt构造器赋值，这里是我们将Parent的prototype属性赋值给了变量P，在通过p来完成uber赋值的。之所以要故意做出这种差异化实现只是为了说明，可以根据自己的需要来使用合适的继承模式
	console.log(td.toString());

	// TwoDShape并没有重新定义name属性，所以在这里打印了两个shape，我们可以在任何时候重新定义name属性，然后所有的实例都会立即看到name属性的更新
	TwoDShape.prototype.name = '2D Shape';
	console.log(td.toString());
</script>
</body>
</html>